/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.java.app.hacktouch.gesture

import android.app.Activity
import android.app.ListActivity
import android.content.Context
import android.content.pm.ActivityInfo
import android.gesture.Gesture
import android.graphics.Bitmap
import android.graphics.Color
import android.os.AsyncTask
import android.os.Bundle
import android.os.Environment
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ImageSpan
import android.util.Log
import android.view.*
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.TextView
import android.widget.Toast
import com.java.app.hacktouch.MainActivity
import com.java.app.hacktouch.R
import java.io.File
import java.util.*

class RemoveGestureActivity : ListActivity() {

    private val mStoreFile = File(Environment.getExternalStorageDirectory(), "gestures")

    private val mSorter = Comparator<NamedGesture> { object1, object2 -> object1.name!!.compareTo(object2.name!!) }

    private var mAdapter: GesturesAdapter? = null
    private var mTask: GesturesLoadTask? = null
    private var mEmpty: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        requestedOrientation = ActivityInfo
                .SCREEN_ORIENTATION_LANDSCAPE //横屏

        setContentView(R.layout.remove_gesture)

        mEmpty = findViewById(android.R.id.empty)
        mAdapter = GesturesAdapter(this)
        listAdapter = mAdapter

        loadGestures()
        registerForContextMenu(listView)
    }

    private fun loadGestures() {
        if (mTask != null && mTask!!.status != AsyncTask.Status.FINISHED) {
            mTask!!.cancel(true)
        }
        mTask = GesturesLoadTask().execute() as GesturesLoadTask
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Log.i(TAG, "RemoveGesture Back")
            if (mTask != null && mTask!!.status != AsyncTask.Status.FINISHED) {
                mTask!!.cancel(true)
                mTask = null
            }
            setResult(Activity.RESULT_OK)
            finish()
        }
        return false
    }

    private fun checkForEmpty() {
        if (mAdapter!!.count == 0) {
            mEmpty!!.setText(R.string.gestures_empty)
        }
    }

    override fun onCreateContextMenu(menu: ContextMenu, v: View,
                                     menuInfo: ContextMenu.ContextMenuInfo) {

        super.onCreateContextMenu(menu, v, menuInfo)

        val info = menuInfo as AdapterView.AdapterContextMenuInfo
        menu.setHeaderTitle((info.targetView as TextView).text)
        menu.add(0, MENU_ID_REMOVE, 0, R.string.gestures_delete)
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        val menuInfo = item.menuInfo as AdapterView.AdapterContextMenuInfo
        val gesture = menuInfo.targetView.tag as NamedGesture

        when (item.itemId) {
            MENU_ID_REMOVE -> {
                deleteGesture(gesture)
                return true
            }
        }

        return super.onContextItemSelected(item)
    }

    private fun deleteGesture(gesture: NamedGesture) {
        sStore!!.removeGesture(gesture.name, gesture.gesture)
        sStore.save()

        val adapter = mAdapter
        adapter!!.setNotifyOnChange(false)
        adapter.remove(gesture)
        adapter.sort(mSorter)
        checkForEmpty()
        adapter.notifyDataSetChanged()

        Toast.makeText(this, R.string.gestures_delete_success, Toast.LENGTH_SHORT).show()
    }

    private inner class GesturesLoadTask : AsyncTask<Void, NamedGesture, Int>() {
        private var mThumbnailSize: Int = 0
        private var mThumbnailInset: Int = 0
        private var mPathColor: Int = 0

        override fun onPreExecute() {
            super.onPreExecute()

            val resources = resources
            mPathColor = resources.getColor(R.color.gesture_color)
            mThumbnailInset = resources.getDimension(R.dimen.gesture_thumbnail_inset).toInt()
            mThumbnailSize = resources.getDimension(R.dimen.gesture_thumbnail_size).toInt()

            mAdapter!!.setNotifyOnChange(false)
            mAdapter!!.clear()
        }

        override fun doInBackground(vararg params: Void): Int? {
            if (isCancelled) return STATUS_CANCELLED
            if (Environment.MEDIA_MOUNTED != Environment.getExternalStorageState()) {
                return STATUS_NO_STORAGE
            }

            val store = sStore

            if (store!!.load()) {
                for (name in store.gestureEntries) {
                    if (isCancelled) break

                    for (gesture in store.getGestures(name)) {
                        val bitmap = gesture.toBitmap(mThumbnailSize, mThumbnailSize,
                                mThumbnailInset, mPathColor)
                        val namedGesture = NamedGesture()
                        namedGesture.gesture = gesture
                        namedGesture.name = name

                        mAdapter!!.addBitmap(namedGesture.gesture!!.id, bitmap)
                        publishProgress(namedGesture)
                    }
                }

                return STATUS_SUCCESS
            }

            return STATUS_NOT_LOADED
        }

        override fun onProgressUpdate(vararg values: NamedGesture) {
            super.onProgressUpdate(*values)

            val adapter = mAdapter
            adapter!!.setNotifyOnChange(false)

            for (gesture in values) {
                adapter.add(gesture)
            }

            adapter.sort(mSorter)
            adapter.notifyDataSetChanged()
        }

        override fun onPostExecute(result: Int?) {
            super.onPostExecute(result)

            if (result == STATUS_NO_STORAGE) {
                listView.visibility = View.GONE
                mEmpty!!.visibility = View.VISIBLE
                mEmpty!!.text = getString(R.string.gestures_error_loading,
                        mStoreFile.absolutePath)
            } else {
                checkForEmpty()
            }
        }
    }

    internal class NamedGesture {
        var name: String? = null
        var gesture: Gesture? = null
    }

    private inner class GesturesAdapter(context: Context) : ArrayAdapter<NamedGesture>(context, 0) {
        private val mInflater: LayoutInflater
        private val mThumbnails = Collections.synchronizedMap(
                HashMap<Long, Bitmap>())

        init {
            mInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        }

        internal fun addBitmap(id: Long?, bitmap: Bitmap) {
            mThumbnails.put(id, bitmap)
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            var convertView = convertView
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.gestures_item, parent, false)
            }

            val gesture = getItem(position)
            val label = convertView as TextView?

            label!!.tag = gesture
            label.setBackgroundColor(Color.GRAY)

            val imgSpan = ImageSpan(this@RemoveGestureActivity.applicationContext,
                    mThumbnails[gesture!!.gesture!!.id])
            val spanString = SpannableString("    " + gesture.name!!)
            spanString.setSpan(imgSpan, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            label.text = spanString
            return convertView!!
        }
    }

    companion object {
        private val STATUS_SUCCESS = 0
        private val STATUS_CANCELLED = 1
        private val STATUS_NO_STORAGE = 2
        private val STATUS_NOT_LOADED = 3

        private val MENU_ID_REMOVE = 2

        private val TAG = "RemoveGestureActivity"

        private val sStore = MainActivity.store
    }
}
